package com.datas.service;

import com.datas.beans.LoginProfile;
import com.datas.db.hibernatebeans.UmsUser;
import com.datas.db.hibernatebeans.UmsUserLoginToken;
import com.datas.utils.hbn.HbnTxRuner;
import org.apache.commons.codec.digest.DigestUtils;
import org.hibernate.Session;
import org.slf4j.LoggerFactory;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

/**
 * Created by jige0727 on 2017/5/29.
 */
@Service
public class LoginService {
    /**
     * 获取token
     *
     * @param username 账号
     * @param password 密码 未加密的
     * @return
     */
    public UmsUserLoginToken getAccessToken(String username, String password) {
        UmsUserLoginToken token = (UmsUserLoginToken) new HbnTxRuner() {
            @Override
            protected Object dataLogic() throws Exception {
                Integer userid = checkUsernameAndPass(username, UmsUser.encodePass(password).toLowerCase(), getCurrentSession());
                LoggerFactory.getLogger(getClass()).info("userid -> " + userid);
                if (userid != null) {
                    UmsUserLoginToken tokenInDb = getTokenInDB(userid, "ums", getCurrentSession());
                    if (tokenInDb != null) {
                        tokenInDb.setLoginTime(new Date());
                        getCurrentSession().update(tokenInDb);
                        return tokenInDb;
                    } else {
                        UmsUserLoginToken token = generateLoginToken(userid, "ums");
                        deleteTokenBefore(userid, "ums", getCurrentSession());
                        getCurrentSession().save(token);
                        return token;
                    }
                }
                return null;
            }
        }.runTx();
        return token;
    }

    /**
     * 根据用户id获取现有的token
     *
     * @param userid
     * @param userType
     * @param session
     * @return
     */
    private UmsUserLoginToken getTokenInDB(Integer userid, String userType, Session session) {
        String hql = "from UmsUserLoginToken u where u.users_id=:userid and u.userType=:userType ";
        return (UmsUserLoginToken) session.createQuery(hql)
                .setParameter("userid", userid)
                .setParameter("userType", userType)
                .uniqueResult();
    }

    private Integer checkUsernameAndPass(String username, String password, Session session) throws Exception {
        String hql = "select u.id from UmsUser u where u.username=:username and u.password=:password";
        return (Integer) session.createQuery(hql)
                .setParameter("username", username)
                .setParameter("password", password)
                .uniqueResult();
    }

    /**
     * 保存登录token 并返回
     *
     * @return
     */
    private UmsUserLoginToken generateLoginToken(Integer userid, String userType) throws Exception {
        Date loginTime = new Date();
        String access_token = "AT-" + UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();

        UmsUserLoginToken tokenData = new UmsUserLoginToken();
        tokenData.setUsers_id(userid);
        tokenData.setLoginTime(loginTime);
        tokenData.setAccess_token(access_token);
        tokenData.setUserType(userType);
        return tokenData;
    }

    private Integer deleteTokenBefore(Integer userid, String userType, Session session) throws Exception {
        String hql = "delete from UmsUserLoginToken where users_id =:userid and userType=:userType ";
        Integer res = session.createQuery(hql)
                .setParameter("userid", userid)
                .setParameter("userType", userType)
                .executeUpdate();
        return res;
    }

    /**
     * 验证token 获取账号信息
     *
     * @param access_token token
     * @return
     */
    public LoginProfile validProfile(String access_token) {
        LoggerFactory.getLogger(getClass()).info("access_token -> " + access_token);
        LoginProfile profile = (LoginProfile) new HbnTxRuner() {
            @Override
            protected Object dataLogic() throws Exception {
                String hql = "SELECT new com.datas.beans.LoginProfile( usr.real_name, usr.username, usr.id ) " +
                        "FROM UmsUserLoginToken tkn " +
                        "INNER JOIN UmsUser usr ON usr.id = tkn.users_id " +
                        "WHERE usr.disabled=0 and tkn.access_token =:access_token and tkn.userType ='ums' ";
                LoginProfile res = (LoginProfile) getCurrentSession().createQuery(hql).setParameter("access_token", access_token)
                        .uniqueResult();
                return res;
            }
        }.runTx();
        return profile;
    }

    /**
     * 专家的登录
     *
     * @param username
     * @param password
     * @return
     */
    public UmsUserLoginToken getAccessTokenExpert(String username, String password) {
        UmsUserLoginToken token = (UmsUserLoginToken) new HbnTxRuner() {
            @Override
            protected Object dataLogic() throws Exception {
                Integer userid = checkUsernameAndPassExpert(username, UmsUser.encodePass(password).toUpperCase(), getCurrentSession());
                LoggerFactory.getLogger(getClass()).info("userid -> " + userid);
                if (userid != null) {
                    UmsUserLoginToken tokenInDb = getTokenInDB(userid, "expert", getCurrentSession());
                    if (tokenInDb != null) {
                        tokenInDb.setLoginTime(new Date());
                        getCurrentSession().update(tokenInDb);
                        return tokenInDb;
                    } else {
                        UmsUserLoginToken token = generateLoginToken(userid, "expert");
                        deleteTokenBefore(userid, "expert", getCurrentSession());
                        getCurrentSession().save(token);
                        return token;
                    }
                }
                return null;
            }
        }.runTx();
        return token;
    }

    private Integer checkUsernameAndPassExpert(String username, String password, Session session) throws Exception {
        String sql = "SELECT i.EXPT_ID FROM T_EXPT_INF i WHERE i.MOB_NBR = :username AND i.EXPT_PSW = :password";
        Object data = session.createNativeQuery(sql)
                .setParameter("username", username)
                .setParameter("password", password)
                .uniqueResult();
        if (data == null) {
            return null;
        }
        return Integer.parseInt("" + data);
    }

    public LoginProfile validProfileExpert(String access_token) {
        LoggerFactory.getLogger(getClass()).info("access_token -> " + access_token);
        LoginProfile profile = (LoginProfile) new HbnTxRuner() {
            @Override
            protected Object dataLogic() throws Exception {
                Integer userid = getUseridByToken(access_token, getCurrentSession());
                return getExpertProfile(userid, getCurrentSession());
            }

            private Integer getUseridByToken(String access_token, Session session) {
                String hql = "SELECT tkn.users_id " +
                        "FROM UmsUserLoginToken tkn " +
                        "WHERE tkn.access_token =:access_token and tkn.userType ='expert' ";
                return (Integer) getCurrentSession().createQuery(hql).setParameter("access_token", access_token)
                        .uniqueResult();
            }

            private LoginProfile getExpertProfile(Integer userid, Session session) {
                String sql = "SELECT i.EXPT_ID, i.EXPT_NAM FROM T_EXPT_INF i WHERE i.EXPT_ID = :userid ";
                Object[] datas = (Object[]) session.createNativeQuery(sql)
                        .setParameter("userid", userid)
                        .getSingleResult();
                LoggerFactory.getLogger(getClass()).info("datas -> " + datas[0]);
                LoginProfile profile = new LoginProfile("" + datas[1], "" + datas[1], Integer.parseInt("" + datas[0]));
                return profile;
            }
        }.runTx();
        return profile;
    }

    public String getUserTypeByToken(String access_token) {
        return (String) new HbnTxRuner() {
            @Override
            protected Object dataLogic() throws Exception {
                String hql = "select i.userType from UmsUserLoginToken i where i.access_token=:access_token ";
                return getCurrentSession().createQuery(hql).setParameter("access_token", access_token).uniqueResult();
            }
        }.run();
    }
}
